#pragma once
#include <iostream>
#include <vector>
#include<unistd.h>
#include "Sem.hpp"

using namespace std;
#define Max_Num 5

template <class T>
class ringQueue
{
public:
    ringQueue(int num = Max_Num)
        : _num(num)
        , c_inode(0)
        , p_inode(0)
        , c_sem(0)
        , p_sem(num)
        , _rq(num)
    {
    }

    ~ringQueue() {}

    void Push(const T &in)
    {
        // 生产者：
        p_sem.P();
        pthread_mutex_lock(&p_mutex);
        _rq[p_inode++] = in;
        p_inode %= _num;
        pthread_mutex_unlock(&p_mutex);
        c_sem.V();
    }

    void Pop(T *out)
    {
        // 消费者：
        c_sem.P();
        pthread_mutex_lock(&c_mutex);
        *out = _rq[c_inode++];
        c_inode %= _num;
        pthread_mutex_unlock(&c_mutex);
        p_sem.V();
    }

private:
    vector<T> _rq; // 临界资源区
    int _num;      // vector的上限
    int c_inode;   // 下标
    int p_inode;   // 下标
    Sem c_sem;     // 信号量
    Sem p_sem;     // 信号量

    pthread_mutex_t c_mutex;
    pthread_mutex_t p_mutex;
};
